package com.huilian.iotbox.admin.service.impl;

import com.huilian.iotbox.admin.dao.RolePermissionDao;
import com.huilian.iotbox.admin.service.PermissionService;
import com.huilian.iotbox.admin.service.RolePermissionService;
import com.huilian.iotbox.admin.service.RoleService;
import com.huilian.iotbox.data.common.RedisHelper;
import com.huilian.iotbox.data.common.RedisKey;
import com.huilian.iotbox.data.common.ServerResponse;
import com.huilian.iotbox.data.enums.RoleEnum;
import com.huilian.iotbox.data.po.Permission;
import com.huilian.iotbox.data.po.Role;
import com.huilian.iotbox.data.vo.UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import static java.util.stream.Collectors.toList;

/**
 * @author 少凡
 * @date 2020/2/29 10:26
 */
@Service
public class RolePermissionServiceImpl implements RolePermissionService {


    @Autowired
    private RoleService roleService;
    @Autowired
    private RedisHelper redisHelper;
    @Autowired
    private RolePermissionDao rolePermissionDao;
    @Autowired
    private PermissionService permissionService;
    @Resource
    private RedisTemplate<String, Serializable> redisCacheTemplate;

    @Override
    public ServerResponse authorize(Integer roleId, Integer permissionId) {
        Integer result = rolePermissionDao.authorize(roleId, permissionId);
        if (result == 1) {
            return ServerResponse.createBySuccess();
        } else {
            return ServerResponse.createByError();
        }
    }

    @Override
    public Integer deleteByPermissionId(Integer id) {
        return rolePermissionDao.deleteByPermissionId(id);
    }

    /**
     * 批量授权
     *
     * @param newPermissionIdList 需要授权的授权列表
     * @param roleId              被授权对象
     * @param userInfo            操作人
     * @return
     */
    @Override
    public ServerResponse authorizeBatch(List<Integer> newPermissionIdList, Integer roleId, UserInfo userInfo, Integer platformType) {

        if (RoleEnum.SUPER_ADMINISTRATOR.getRoleId().equals(roleId)) {
            return ServerResponse.createByErrorMessage("超级管理员禁止修改授权！");
        }

        Role role = roleService.getById(roleId);

        //非超级管理员，禁止修改系统角色
        if (!userInfo.getId().equals(1) && role.getAgencyId().equals(0)) {
            return ServerResponse.createByErrorMessage("非超级管理员禁止修改系统角色！");
        }

        List<Integer> noAuthIdList = new ArrayList<>();

        //获取免授权列表
        List<Permission> noAuthList = permissionService.findNoAuthList(platformType);
        for (Permission permission : noAuthList) {
            for (Integer pid : newPermissionIdList) {
                //如果此免授权父ID等授权ID，则此免授权Id，自动加入授权中
                if (permission.getParentId().equals(pid)) {
                    noAuthIdList.add(permission.getId());
                }
            }
        }

        newPermissionIdList.addAll(noAuthIdList);

        /**
         *  查看角色，现有授权(包括选中和未选中的)
         */
        List<Integer> oldPermissionIdList = rolePermissionDao.findPermissionIdListByRoleId(roleId,platformType);

        //交集，原来的，和新传入来的都有此权限(将旧的update checked true)
        List<Integer> intersection = oldPermissionIdList.stream().filter(item -> newPermissionIdList.contains(item)).collect(toList());

        //差集,新传入的不包含旧的，新传入的无，旧的有(将旧的update checked false)
        List<Integer> reduceUpdate = oldPermissionIdList.stream().filter(item -> !newPermissionIdList.contains(item)).collect(toList());

        //差集，旧的没有，新传入的有（insert true）
        List<Integer> reduceInsert = newPermissionIdList.stream().filter(item -> !oldPermissionIdList.contains(item)).collect(toList());

        if (intersection.size() != 0) {
            rolePermissionDao.batchUpdate(intersection, roleId, true);
        }

        if (reduceUpdate.size() != 0) {
            rolePermissionDao.batchUpdate(reduceUpdate, roleId, false);
        }

        if (reduceInsert.size() != 0) {
            rolePermissionDao.batchInsert(reduceInsert, roleId, true);
        }

        final String format = String.format(RedisKey.PERMISSION_USERID_V2, platformType, "*");
        Set<String> permissionDeleteList = redisHelper.keys(format);
        // 使用 RedisConnection 进行管道操作
        redisCacheTemplate.execute((RedisCallback<Void>) connection -> {
            connection.openPipeline(); // 开启管道
            for (String key : permissionDeleteList) {
                connection.del(key.getBytes()); // 删除键
            }
            connection.closePipeline(); // 关闭管道
            return null;
        });
        return ServerResponse.createBySuccess("授权成功！");
    }

    @Override
    public int updateSelectByPermissionId(Integer permissionId, boolean selected) {
        return rolePermissionDao.updateSelectByPermissionId(permissionId, selected);
    }


}
